package com.anjubao.parking.municipal.parkinglot.service;

import com.alibaba.fastjson.JSONObject;
import com.anjubao.parking.municipal.common.dto.ApiResult;
import com.anjubao.parking.municipal.common.global.BusinessCodeEnum;
import com.anjubao.parking.municipal.common.utils.MunicipalParkingUtils;
import com.anjubao.parking.municipal.common.utils.U;
import com.anjubao.parking.municipal.parkinglot.constant.DeviceOperationStatusEnum;
import com.anjubao.parking.municipal.parkinglot.constant.DeviceStatusEnum;
import com.anjubao.parking.municipal.parkinglot.constant.DeviceTypeEnum;
import com.anjubao.parking.municipal.parkinglot.dto.*;
import com.anjubao.parking.municipal.parkinglot.feign.ParkingLotFeignClient;
import com.anjubao.parking.municipal.parkinglot.form.VideoPileAddForm;
import com.anjubao.parking.municipal.parkinglot.form.VideoPileQueryForm;
import com.anjubao.parking.municipal.parkinglot.mapper.ParkingLotDeviceStatusMapper;
import com.anjubao.parking.municipal.parkinglot.mapper.ParkingLotDeviceVideoPileMapper;
import com.anjubao.parking.municipal.parkinglot.mapper.ParkingLotDeviceVideoPileSlotMapper;
import com.anjubao.parking.municipal.parkinglot.model.ParkingLotDeviceStatus;
import com.anjubao.parking.municipal.parkinglot.model.ParkingLotDeviceVideoPile;
import com.anjubao.parking.municipal.parkinglot.model.ParkingLotDeviceVideoPileSlot;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * ParkingLot服务实现类
 *
 * @author chenfang
 */
@Service
@Slf4j
public class ParkingLotDeviceVideoPileService extends ServiceImpl<ParkingLotDeviceVideoPileMapper, ParkingLotDeviceVideoPile> {

    @Resource
    private ParkingLotDeviceVideoPileMapper parkingLotDeviceVideoPileMapper;


    @Resource
    private ParkingLotDeviceVideoPileSlotMapper parkingLotDeviceVideoPileSlotMapper;


    @Autowired
    private ParkingLotFeignClient parkingLotFeignClient;

    @Resource
    private ParkingLotDeviceStatusMapper parkingLotDeviceStatusMapper;

    @Autowired
    private ParkingLotDeviceStatusService parkingLotDeviceStatusService;

    @Value("${syncIp:http://172.25.2.115:8933/sync/device}")
    private String syncIp;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ParkingLotDeviceVideoPileSlotService parkingLotDeviceVideoPileSlotService;

    @Transactional(rollbackFor = Exception.class)
    public ParkingLotDeviceVideoPile saveVideoPile(ParkingLotDeviceVideoPile videoPile, List<ParkingLotDeviceVideoPileSlot> videoPileSlots) {
        //查询停车场，set冗余字段
        videoPile.setParkingLotId(MunicipalParkingUtils.getIdByCode(videoPile.getParkingLotCode()));
        ParkingLotDto parkingLot = parkingLotFeignClient.getParkingLot(videoPile.getParkingLotCode()).getResult();
        videoPile.setParkingLotName(parkingLot.getName()).setParkingLotProvinceId(parkingLot.getProvinceId()).setParkingLotProvinceName(parkingLot.getProvinceName())
                .setParkingLotCityId(parkingLot.getCityId()).setParkingLotCityName(parkingLot.getCityName())
                .setParkingLotDistrictId(parkingLot.getDistrictId()).setParkingLotDistrictName(parkingLot.getDistrictName());
        if (StringUtils.isEmpty(videoPile.getCode())) {//判断是否有code
            videoPile.setId(U.id());//新增
            videoPile.setCode(MunicipalParkingUtils.generateCode(videoPile.getId(), BusinessCodeEnum.PARKING_VIDEO_PILE_CODE.getCode()));
            save(videoPile);
            ParkingLotDeviceStatus parkingLotDeviceStatus = convertDeviceStatusEntity(videoPile, parkingLot);
            parkingLotDeviceStatus.setId(U.id());
            parkingLotDeviceStatus.setCode(MunicipalParkingUtils.generateCode(parkingLotDeviceStatus.getId(), BusinessCodeEnum.DEVICE_STATUS.getCode()));
            parkingLotDeviceStatusMapper.insert(parkingLotDeviceStatus);
        } else {
            videoPile.setId(MunicipalParkingUtils.getIdByCode(videoPile.getCode()));
            updateById(videoPile);//更新
            parkingLotDeviceVideoPileSlotMapper.deleteByVideoPileId(videoPile.getId());
            parkingLotDeviceVideoPileSlotService.saveVideoPileSlot(videoPileSlots);
            ParkingLotDeviceStatus parkingLotDeviceStatus = convertDeviceStatusEntity(videoPile, parkingLot);
            parkingLotDeviceStatusMapper.update(parkingLotDeviceStatus, new UpdateWrapper<ParkingLotDeviceStatus>().eq("device_id", videoPile.getId()));
        }

        return videoPile;
    }

    //    public Page<VideoPileDto> getVideoPiles(Page<VideoPileDto> page, VideoPileQueryForm form) {
//        Page<VideoPileDto> videoPileDtoPage = parkingLotDeviceVideoPileMapper.getVideoPiles(page, form);
//        if (videoPileDtoPage.getTotal() != 0) {
//            List<Long> videoPileIds = new ArrayList<>();
//            for (VideoPileDto videoPileDto : videoPileDtoPage.getRecords()) {
//                videoPileIds.add(MunicipalParkingUtils.getIdByCode(videoPileDto.getCode()));
//            }
//            List<VideoPileSlotDTO> parkingLotDeviceVideoPileSlots = parkingLotDeviceVideoPileSlotMapper.getVideoPileByIds(videoPileIds,form.getParkingSlotIds());
//            //取list-视频桩id 转map
//            Map<String, List<VideoPileSlotDTO>> videoPileSlotsMap = parkingLotDeviceVideoPileSlots.stream().collect(Collectors.toMap(VideoPileSlotDTO::getParkingLotDeviceVideoPileId, s -> {
//                        List<VideoPileSlotDTO> slots = new ArrayList<>();
//                        slots.add(s);
//                        return slots;
//                    },
//                    (List<VideoPileSlotDTO> value1, List<VideoPileSlotDTO> value2) -> {//当key重复时，把旧list加进去新的list
//                        value1.addAll(value2);
//                        return value1;
//                    }
//            ));
//            for (VideoPileDto videoPileDto : videoPileDtoPage.getRecords()) {
//                videoPileDto.setSlots(videoPileSlotsMap.get(String.valueOf(MunicipalParkingUtils.getIdByCode(videoPileDto.getCode()))));
//            }
//        }
//
//        return videoPileDtoPage;
//    }
//
//    public VideoPileDto getVideoPileDto(long id) {
//        return parkingLotDeviceVideoPileMapper.getVideoPileDto(id);
//    }
    public Page<VideoPileDto> getVideoPiles(Page<VideoPileDto> page, VideoPileQueryForm form) {

        ApiResult<List<ParkingLotSlotDto>> parkingLotSlotIds = parkingLotFeignClient.getParkingLotSlotIdsByName(form.getParkingSlot());
        List<String> ids = new ArrayList<>();
        if (parkingLotSlotIds.getResult() != null) {
            for (ParkingLotSlotDto dto : parkingLotSlotIds.getResult()) {
                ids.add(dto.getId());
            }
        }
        form.setParkingSlotIds(ids);
        //如果车位id为空且form.getParkingSlot()不为空 就返回
        if (form.getParkingSlot() != null && ids.size() == 0) {
            return new Page<VideoPileDto>().setRecords(new ArrayList<VideoPileDto>()).setTotal(0L);
        }
        Page<VideoPileDto> videoPileDtoPage = parkingLotDeviceVideoPileMapper.getVideoPiles(page, form);
        if (videoPileDtoPage.getTotal() != 0) {
            List<Long> videoPileIds = new ArrayList<>();
            for (VideoPileDto videoPileDto : videoPileDtoPage.getRecords()) {
                videoPileIds.add(MunicipalParkingUtils.getIdByCode(videoPileDto.getCode()));
            }
            List<VideoPileSlotDTO> parkingLotDeviceVideoPileSlots = parkingLotDeviceVideoPileSlotMapper.getVideoPileByIds(videoPileIds, ids);
            if (parkingLotDeviceVideoPileSlots.size() != 0) {
                // 把feign车位信息合并过来
                Map<String, ParkingLotSlotDto> parkingLotSlotsMap = parkingLotSlotIds.getResult().stream().collect(Collectors.toMap(ParkingLotSlotDto::getId, parkingLotSlotDto -> parkingLotSlotDto));
                for (VideoPileSlotDTO dto : parkingLotDeviceVideoPileSlots) {
                    ParkingLotSlotDto parkingLotSlotDto = parkingLotSlotsMap.get(dto.getParkingLotSlotId());
                    dto.setParkingLotSlotCode(parkingLotSlotDto.getCode()).setParkingLotSlotName(parkingLotSlotDto.getName());
                }
            }

            //取list-视频桩id 转map
            Map<String, List<VideoPileSlotDTO>> videoPileSlotsMap = parkingLotDeviceVideoPileSlots.stream().collect(Collectors.toMap(VideoPileSlotDTO::getParkingLotDeviceVideoPileId, s -> {
                        List<VideoPileSlotDTO> slots = new ArrayList<>();
                        slots.add(s);
                        return slots;
                    },
                    (List<VideoPileSlotDTO> value1, List<VideoPileSlotDTO> value2) -> {//当key重复时，把旧list加进去新的list
                        value1.addAll(value2);
                        return value1;
                    }
            ));
            for (VideoPileDto videoPileDto : videoPileDtoPage.getRecords()) {
                videoPileDto.setSlots(videoPileSlotsMap.get(String.valueOf(MunicipalParkingUtils.getIdByCode(videoPileDto.getCode()))));
            }
        }

        return videoPileDtoPage;
    }

    public VideoPileDto getVideoPileDto(long id) {
        ApiResult<List<ParkingLotSlotDto>> parkingLotSlotIds = parkingLotFeignClient.getParkingLotSlotIdsByName(null);
        Map<String, ParkingLotSlotDto> parkingLotSlotsMap = parkingLotSlotIds.getResult().stream().collect(Collectors.toMap(ParkingLotSlotDto::getId, parkingLotSlotDto -> parkingLotSlotDto));
        VideoPileDto dto = parkingLotDeviceVideoPileMapper.getVideoPileDto(id);
        if (dto.getSlots().size() != 0 && parkingLotSlotsMap.size() != 0) {
            for (VideoPileSlotDTO slotDTO : dto.getSlots()) {
                slotDTO.setParkingLotSlotName(parkingLotSlotsMap.get(slotDTO.getParkingLotSlotId()).getName())
                        .setParkingLotSlotCode(parkingLotSlotsMap.get(slotDTO.getParkingLotSlotId()).getCode());
            }
        }
        return dto;
    }

    public void deleteVideoPile(long id) {
        parkingLotDeviceVideoPileMapper.deleteById(id);
        parkingLotDeviceVideoPileSlotMapper.deleteByVideoPileId(id);
        parkingLotDeviceStatusMapper.delete(new QueryWrapper<ParkingLotDeviceStatus>().eq("device_id", id));

    }

    private ParkingLotDeviceStatus convertDeviceStatusEntity(ParkingLotDeviceVideoPile videoPile, ParkingLotDto parkingLot) {
        ParkingLotDeviceStatus parkingLotDeviceStatus = new ParkingLotDeviceStatus();
        //todo
//        parkingLotDeviceStatus.setParkingLotSlotId(videoPile.getParkingLotSlotId());
//        parkingLotDeviceStatus.setParkingLotSlotCode(videoPile.getParkingLotSlotCode());
//        parkingLotDeviceStatus.setParkingLotSlotName(videoPile.getParkingLotSlotName());
        parkingLotDeviceStatus.setDeviceId(videoPile.getId());
        parkingLotDeviceStatus.setDeviceCode(videoPile.getCode());
        parkingLotDeviceStatus.setDeviceName(videoPile.getName());
        parkingLotDeviceStatus.setDeviceType(DeviceTypeEnum.VIDEO_PILE.getCode());
        parkingLotDeviceStatus.setIsOnline(DeviceOperationStatusEnum.OnLine.getCode());
        parkingLotDeviceStatus.setStatus(DeviceStatusEnum.Normal.getCode());
        parkingLotDeviceStatus.setProvinceId(videoPile.getParkingLotProvinceId());
        parkingLotDeviceStatus.setProvinceName(videoPile.getParkingLotProvinceName());
        parkingLotDeviceStatus.setCityId(videoPile.getParkingLotCityId());
        parkingLotDeviceStatus.setCityName(videoPile.getParkingLotCityName());
        parkingLotDeviceStatus.setDistrictId(videoPile.getParkingLotDistrictId());
        parkingLotDeviceStatus.setDistrictName(videoPile.getParkingLotDistrictName());
        parkingLotDeviceStatus.setLocation(parkingLot.getLocation());
        parkingLotDeviceStatus.setNote(videoPile.getNote());
//        parkingLotDeviceStatus.setFixBy(null);
//        parkingLotDeviceStatus.setFixTime(null);
//        parkingLotDeviceStatus.setFixNote(null);
        parkingLotDeviceStatus.setLastReportTime(LocalDateTime.now());
        return parkingLotDeviceStatus;
    }

    public static void main(String[] args) {
        Lists.newArrayList();
    }

    public void updateStatus(String onlineStatus, String videoPileCode) {
        parkingLotDeviceStatusMapper.updateStatus(onlineStatus, videoPileCode);
    }

    public void syncVideoPile(ParkingLotDeviceVideoPile videoPile,List<ParkingLotDeviceVideoPileSlot> slots) {
        QueryWrapper<ParkingLotDeviceStatus> queryWrapper=new QueryWrapper();
        queryWrapper.eq("device_id",videoPile.getId());
        //获取设备状态
        ParkingLotDeviceStatus deviceStatus=parkingLotDeviceStatusMapper.selectOne(queryWrapper);

        //路边停车场接口dto
        RoadSideVideoPileDto roadSideVideoPileDto=new RoadSideVideoPileDto();

        roadSideVideoPileDto.setDeviceCode(videoPile.getCode());
        roadSideVideoPileDto.setDeviceId(videoPile.getId());
        roadSideVideoPileDto.setDeviceName(videoPile.getName());
        roadSideVideoPileDto.setDeviceStatus(deviceStatus.getStatus());
        roadSideVideoPileDto.setIpAddr(videoPile.getIpAddr());
        roadSideVideoPileDto.setIsOnline(deviceStatus.getIsOnline());
        roadSideVideoPileDto.setLocation(deviceStatus.getLocation());
        roadSideVideoPileDto.setMachineNo(videoPile.getMachineNo());
        roadSideVideoPileDto.setParkingLotCode(videoPile.getParkingLotCode());
        roadSideVideoPileDto.setParkingLotId(videoPile.getParkingLotId());
        roadSideVideoPileDto.setParkingLotName(videoPile.getParkingLotName());

        List<Long> parkingLotSlotId=new ArrayList<>();
        for(ParkingLotDeviceVideoPileSlot slot:slots){
            parkingLotSlotId.add(slot.getParkingLotSlotId());
        }

        roadSideVideoPileDto.setParkingLotSlotId(parkingLotSlotId);

//        roadSideVideoPileDto.setRemainingBattery(deviceStatus.getRemainingBattery());
        roadSideVideoPileDto.setVideoPileType(deviceStatus.getDeviceType());


        ApiResult<String> res = this.restTemplate.postForObject(syncIp, roadSideVideoPileDto, ApiResult.class);


    }

    public void syncDelete(String videoPileCode) {

        String url=syncIp+"/"+MunicipalParkingUtils.getIdByCode(videoPileCode);
        this.restTemplate.delete(url);
    }
}
